<?php
/*
 * description：
 * author：wh
 * email：
 * createTime：{2020/6/2} {16:14}
 */

namespace wanghua\general_utility_tools_php\tool;

use FFMpeg\Coordinate\TimeCode;
use FFMpeg\FFMpeg;
use wanghua\general_utility_tools_php\tool\Tools;

/**
 * 视频处理工具
 *
 *     环境要求：
 *          PHP7.0+，ThinkPHP5.1+,linux ffmpeg插件安装最新版
 *
 *      配置参数：
 *          在config配置文件中
 *
 *
 * Class Video
 * @package libraries
 */
class Video
{
    private $config = [];
    public function __construct($config=[
        'ffmpeg.binaries' => '/usr/bin/ffmpeg',  // 或者其他FFmpeg实际路径
        'ffprobe.binaries' => '/usr/bin/ffprobe', // 或者其他ffprobe实际路径
    ])
    {
        $this->config = $config;
    }

    /**
     * desc：【不推荐】生成视频封面
     * 读取视频第一帧保存为图片
     * author：wh
     * @param $in_file 待处理视频路径（物理路径）
     * @param $out_file_name 缩略图文件名称(带后缀)
     * @param $path 指定存储路径
     * @return string
     */
    function createVideoImg($in_file, $out_file_name, $path=''){
        //缩略图保存路径
        $path = $path?$path:'/public/uploads/video_cover/'.date('Ymd').'/';
        $out_file = Tools::get_root_path().$path;

        if(!file_exists($out_file)){
            mkdir($out_file, 0777, true);
        }
        $out_file_path = $out_file.$out_file_name;
        //要执行的 cmd 命令
        //$cmd =  "ffmpeg -i ".$in_file." -y -f image2 -ss 2 -t 0.001 -s 350x240 ".$out_file;
        $cmd = "ffmpeg -i {$in_file} -f image2 -ss 2 -t 0.001 {$out_file_path}";
        $cmd = iconv('UTF-8','GB2312',$cmd);
        //执行命令
        exec($cmd);
        return $path.$out_file_name;
    }
    /**
     * desc：【不推荐】生成视频封面
     * 读取视频第一帧保存为图片
     * 注：仅适用于thinkPHP6
     * author：wh
     * @param $in_file 待处理视频路径
     * @param $out_file_name 缩略图文件名称
     * @return string
     */
    function toCreateVideoImg($in_file, $out_file_name, $path=''){
        //缩略图保存路径
        $path = $path?$path:'/static/upload/file/user_video_img/';
        $out_file = Tools::get_root_path().'public'.$path;

        if(!file_exists($out_file)){
            mkdir($out_file, 0777, true);
        }
        $out_file_path = $out_file.$out_file_name;
        //要执行的 cmd 命令
        //$cmd =  "ffmpeg -i ".$in_file." -y -f image2 -ss 2 -t 0.001 -s 350x240 ".$out_file;
        $cmd = "ffmpeg -i {$in_file} -f image2 -ss 2 -t 0.001 {$out_file_path}";
        $cmd = iconv('UTF-8','GB2312',$cmd);
        //执行命令
        exec($cmd);
        return $path.$out_file_name;
    }

    /**
     * desc：【推荐】创建视频封面
     * 依赖：
     *     composer require php-ffmpeg/php-ffmpeg
     *
     * 安装参考文章：
     * https://blog.csdn.net/qq_15941409/article/details/137846947?spm=1001.2014.3001.5501
     * author：wh
     * @param string $inputVideoPath 视频物理路径
     * @param string $out_file_name 带后缀的封面文件名
     * @param string $path 封面输出物理目录，不存在会自动创建目录
     * @return string
     */
    function createVideoCoverImage($inputVideoPath, $out_file_name='', $path=''){
        // 初始化FFMpeg实例，指向FFmpeg可执行文件的路径（根据实际情况调整路径）
        $ffmpeg = FFMpeg::create($this->config);
        // 指定输出图像文件的路径和格式（例如，输出为JPEG格式）
        $filename = $out_file_name?:Tools::rand_str(32) . '.jpg';
        $path = $path?:Tools::get_root_path() . 'public/uploads/video_cover/' .date('Ymd').'/';
        if(!file_exists($path)){
            mkdir($path, 0777, true);
        }
        $outputImage = $path. $filename;  // 替换为保存第一帧的路径
        // 打开视频文件
        $video = $ffmpeg->open($inputVideoPath);
        // 提取第一帧（默认情况下，FFMpeg库将从视频的开始处获取第一帧）
        $frame = $video->frame(TimeCode::fromSeconds(0));
        // 将第一帧保存到指定的图像文件
        $frame->save($outputImage, 'image/jpeg');
        return $outputImage;
    }
}